extends Node2D

# 网格大小
@export var grid_width: int = 8
@export var grid_height: int = 8
@export var generate_index: int = 5

# 方块预制体
@export var block_scene: PackedScene

# 存储所有方块的二维数组
var grid = []

# 当前选中的方块
var selected_block = null

# 分数
var score = 0;


# 初始化函数
func _ready():
	generate_grid()
	for x in range(grid_width):
		for y in range(grid_height):
			grid[x][y].connect("swapped_with", Callable(self, "_on_block_swapped"))

func block_animation(block,position):
	var tween = get_tree().create_tween()
	tween.tween_property(block, "position", position, 0.4).set_ease(Tween.EASE_IN_OUT).set_trans(Tween.TRANS_LINEAR)

func _on_block_swapped(block1):
	if selected_block == null:
		# 如果没有选中任何方块，记录当前方块为选中方块
		selected_block = block1
		print("Selected block: ", block1)
		block1.setOverlay(true)
	else:
		block1.setOverlay(true)
		# 如果已经选中了一个方块，尝试交换
		var block2 = selected_block
		if are_adjacent(block1, block2):
			swap_blocks(block1, block2)
			await get_tree().create_timer(0.5).timeout
			if check_matches(block1, block2):
				# 如果没有匹配，交换回来
				print("No matches found. Swapping back...")
				await get_tree().create_timer(0.4).timeout
				swap_blocks(block1, block2)
		else:
			print("Blocks are not adjacent.")
		# 清空选中的方块
		selected_block = null
		block1.setOverlay(false)
		block2.setOverlay(false)


func are_adjacent(block1, block2):
	# 判断两个方块是否相邻
	var pos1 = block1.position
	var pos2 = block2.position
	return abs(pos1.x - pos2.x) + abs(pos1.y - pos2.y) == 64

func swap_blocks(block1, block2):
	
	# 更新网格数组
	var x1 = 0
	var y1 = 0
	var x2 = 0
	var y2 = 0
	for x in range(grid_width):
		for y in range(grid_height):
			if grid[x][y] == block1:
				x1 = x
				y1 = y
			if grid[x][y] == block2:
				x2 = x
				y2 = y
	# 交换网格中的方块
	var temp = grid[x1][y1]
	grid[x1][y1] = grid[x2][y2]
	grid[x2][y2] = temp

	# 交换两个方块的位置
	block_animation(block1,block2.position)
	block_animation(block2,block1.position)
	
# 生成网格
func generate_grid():
	for x in range(grid_width):
		var column = []
		for y in range(grid_height):
			# 实例化方块
			var block = block_scene.instantiate()  # 修改这里
			# 设置方块位置
			block.position = Vector2(x * 64, y * 64)  # 假设每个方块大小为 64x64
			# 随机设置方块类型
			block.block_type = randi() % generate_index
			# 将方块添加到 Grid 节点
			$Grid.add_child(block)
			# 记录到二维数组
			column.append(block)
		grid.append(column)
# 打印网格（调试用）
func print_grid():
	for y in range(grid_height):
		var row = ""
		for x in range(grid_width):
			row += str(grid[x][y].block_type) + " "
		print(row)
		
	print("----------------")
	
# 检查是否有可消除的方块
func check_matches(block1, block2):
	var restore = true
	var to_remove = {}  # 使用字典模拟集合，避免重复存储需要消除的方块
	# 检查横向匹配
	for x in range(grid_width):
		for y in range(grid_height):
			var matches = find_horizontal_match(x, y)
			if matches.size() >= 3:
				for block in matches:
					if block == block1 or block == block2:
						restore = false
					to_remove[block] = true  # 使用字典键来存储唯一方块
	# 检查纵向匹配
	for x in range(grid_height):
		for y in range(grid_width):
			var matches = find_vertical_match(x, y)
			if matches.size() >= 3:
				for block in matches:
					if block == block1 or block == block2:
						restore = false
					to_remove[block] = true  # 使用字典键来存储唯一方块
	# 消除匹配的方块
	for block in to_remove.keys():
		score = score+1;
		$ScoreTextLabel.text = "Score: "+str(score)
		remove_block(block)
	return restore
	
	
# 查找横向匹配
func find_horizontal_match(start_x, start_y) -> Array:
	var matches = []
	if grid[start_x][start_y] == null:
		return matches
	
	var type = grid[start_x][start_y].block_type
	var x = start_x
	
	# 向右查找匹配
	while x < grid_width and grid[x][start_y] != null and grid[x][start_y].block_type == type and grid[x][start_y].block_type != 5:
		matches.append(grid[x][start_y])
		x += 1
	
	# 向左查找匹配
	x = start_x - 1
	while x >= 0 and grid[x][start_y] != null and grid[x][start_y].block_type == type and grid[x][start_y].block_type != 5:
		matches.append(grid[x][start_y])
		x -= 1
	
	return matches

# 查找纵向匹配
func find_vertical_match(start_x, start_y) -> Array:
	var matches = []
	
	if grid[start_x][start_y] == null:
		return matches
	
	var type = grid[start_x][start_y].block_type
	var y = start_y
	
	# 向下查找匹配
	while y < grid_height and grid[start_x][y] != null and grid[start_x][y].block_type == type and grid[start_x][y].block_type != 5:
		matches.append(grid[start_x][y])
		y += 1
	
	# 向上查找匹配
	y = start_y - 1
	while y >= 0 and grid[start_x][y] != null and grid[start_x][y].block_type == type and grid[start_x][y].block_type != 5:
		matches.append(grid[start_x][y])
		y -= 1
	
	return matches

# 移除方块
func remove_block(block):
	block.queue_free()
	var x = 0
	var y = 0
	# 找到方块在网格中的位置
	for i in range(grid_width):
		for j in range(grid_height):
			if grid[i][j] == block:
				x = i
				y = j
				break
	## 生成新的方块
	var new_block = block_scene.instantiate()
	new_block.position = block.position
	new_block.block_type = randi() % generate_index
	$Grid.add_child(new_block)
	grid[x][y] = new_block
	grid[x][y].connect("swapped_with", Callable(self, "_on_block_swapped"))
